/***************************************************************
*
* DS_TYPEID.CPP
*
* Type identification (helps getting rid of RTTI/dynamic_cast
* in many circumstances, as well as of various 'sign'/classIDs
*
***************************************************************/
#include <ap/settings/ds_settings.h>

#include "ap\ap_comm.h"
#include "ds_typeid.h"

/***************************************************************
* dsTYPE_ID_SYS::dsTYPE_ID_SYS()
*
***************************************************************/
dsTYPE_ID_SYS::dsTYPE_ID_SYS () : curTypeNmb(0)
{
}

/***************************************************************
* dsTYPE_ID_SYS::CalcTypeID()
*
***************************************************************/
void dsTYPE_ID_SYS::CalcTypeID (dsTYPE_ID * newTypeID, dsTYPE_ID * baseTypeID)
{
   if (curTypeNmb >= dsTYPE_ID::BIT_ARRAY::CAPACITY) {
      STRONG_ASSERT(FALSE);
      return;
   }

   if (baseTypeID == NULL) {
      newTypeID->id.Set(0);
   } else {
      ASSERT(baseTypeID->IsInited());
      *newTypeID = *baseTypeID;
      newTypeID->id.Set(curTypeNmb);
   }

   curTypeNmb++;
   return;
}

/***************************************************************
* dsTYPE_ID::IsDerivedFrom()
*
***************************************************************/
BOOL dsTYPE_ID::IsDerivedFrom (const dsTYPE_ID & baseTypeID) const
{
   // make sure 'baseTypeID' was properly initialized
   STRONG_ASSERT(baseTypeID.IsInited());

   BOOL rc1 = TRUE;
   for (int i = 0; i < BIT_ARRAY::DWORD_COUNT; i++) {
      if ((id.GetAt(i) & baseTypeID.id.GetAt(i)) != baseTypeID.id.GetAt(i)) {
         return FALSE;
      }
   }

   return TRUE;
};

/***************************************************************
* dsTYPE_ID::GetCommonAncestor ()
*
***************************************************************/
dsTYPE_ID dsTYPE_ID::GetCommonAncestor (const dsTYPE_ID& id1, const dsTYPE_ID& id2)
{
   dsTYPE_ID result;
   for (int i = 0; i < dsTYPE_ID::BIT_ARRAY::DWORD_COUNT; i++) {
      result.id.SetYesMask(i * 32, id1.id.GetAt(i) & id2.id.GetAt(i));
   } 
   return result;
}